package stack;

import java.util.List;

public class Stack<T>  implements NtStack<T>{

	final static int DEFAULT_CAPACITY = 50;
	final static int RESIZE_CAPACITY = 10;
	
	private int capacity;
	private T[] stackValue;
	private int peak = 0;
	
	private boolean usedDefaultSize;
	
	@SuppressWarnings("unchecked")
	public Stack() {
		//
		this.usedDefaultSize = true;
		this.capacity = DEFAULT_CAPACITY;
		this.stackValue = (T[]) new Object[capacity];
	}
	
	@SuppressWarnings("unchecked")
	public Stack(int optionalSize) {
		//
		this.usedDefaultSize = false;
		this.capacity = optionalSize;
		this.stackValue = (T[]) new Object[optionalSize];
	}
	
	@Override
	public int size() {
		//
		if(peak < 0 )
			return 0;
		
		return peak;
	}

	@Override
	public void push(T element) {
		//
		if (!usedDefaultSize && isStackOverFlow()) {
				resizeArray();
		}
		this.stackValue[peak] = element;
		peak ++;
	}
	
	@Override
	public T pop() {
		//
		if (peak > 0) {
			T element = stackValue[peak-1];
			stackValue[peak-1] = null;
			this.peak --;
			return element;
		} else {
			System.out.println("stack is empty ");
		}
		return null;
	}
	
	public T[] toArray() {
		return this.stackValue;
	}
	
	private boolean isStackOverFlow() {
		//
		if (capacity > this.peak) {
			return false;
		}
		return true;
	}

	@SuppressWarnings("unchecked")
	private void resizeArray() {
		this.capacity = capacity+RESIZE_CAPACITY;
		
		T[] newArray = (T[]) new Object[capacity];
		System.arraycopy(this.stackValue, 0, newArray, 0, stackValue.length);
		this.stackValue = newArray;
	}
	
	public boolean isEmpty(){
		if(peak == 0) {
			return true;
		}
		return false;
	}
	
	public Stack<T> read(List<T> storage) {
		//
		for (T element : storage) {
			this.push(element);
		}
		return this;
	}
}
